package com.ynet.hm.utils.rsa;


import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;  
import java.security.KeyPair;  
import java.security.KeyPairGenerator;  
import java.security.NoSuchAlgorithmException;  
import java.security.PrivateKey;  
import java.security.PublicKey;  
import java.security.SecureRandom;  
import java.security.Signature;  
import java.security.spec.PKCS8EncodedKeySpec;  
import java.security.spec.X509EncodedKeySpec;  
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;  
import java.util.logging.Level;  
import java.util.logging.Logger;  
  
public class RSAHelper {  
    public static final String KEY_ALGORITHM = "RSA";  
    public static final String PUBLIC_KEY = "PublicKey";  
    public static final String PRIVATE_KEY = "PrivateKey";  
    private static final String SIGNATURE_ALGORITHM = "MD5withRSA";  
  
    public RSAHelper() {  
    }  
  /**
   * 
   * @param keyMap
   * 获取公私钥对
 * @return 
 * @throws UnsupportedEncodingException 
   * 
   */
    public static Map generateKeyPair(){  
        boolean result = false;  
        Map keyMap = new HashMap() ;
        KeyPairGenerator keyPairGenerator = null;  
        try {  
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");  
            result = true;  
        } catch (NoSuchAlgorithmException ex) {  
            Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,  
                    ex);  
        }  
  
        if (result) {  
            SecureRandom secureRandom = new SecureRandom();  
  
            String currentDateTime = new SimpleDateFormat("yyyyMMddHHmmssSSS")  
                    .format(new Date());  
            secureRandom.setSeed(currentDateTime.getBytes());  
  
            keyPairGenerator.initialize(1024, secureRandom);  
  
            KeyPair keyPair = keyPairGenerator.genKeyPair();  
  
            PublicKey publicKey = keyPair.getPublic();  
            PrivateKey privateKey = keyPair.getPrivate();  
  
            keyMap.put(RSAHelper.PUBLIC_KEY,Base64.getEncoder().encodeToString(publicKey.getEncoded()));
            keyMap.put(RSAHelper.PRIVATE_KEY, Base64.getEncoder().encodeToString(privateKey.getEncoded()));  

            
            return keyMap;
        }
		return keyMap;  
    }  
  
  /**
   * 
   * @param strData 源数据字符串
   * @param strPrivateKeyBytes  签名私钥
   * @return String
   * 通过私钥签名
   */
    public static String sign(String strData,   String strPrivateKeyBytes) {  
        byte[] signedData = null;  
        
        byte[] privateKeyBytes =Base64.getDecoder().decode(strPrivateKeyBytes);
        try {  
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(  
                    privateKeyBytes);  
  
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  
            PrivateKey privateKey = keyFactory  
                    .generatePrivate(pkcs8EncodedKeySpec);  
  
            Signature signature = Signature.getInstance(RSAHelper.SIGNATURE_ALGORITHM);  
  
            signature.initSign(privateKey);  
            byte[] data = strData.getBytes();
            
            signature.update(data);  
  
            signedData = signature.sign();  
        } catch (Exception ex) {  
            Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,  
                    ex);  
        }  
  
        return Base64.getEncoder().encodeToString(signedData);
    }  
    

    /**
     * 
     * @param strData            数据明文串
     * @param strPublicKeyBytes  验签公钥
     * @param strDataSignature   签名数据
     * @return boolean
     * 通过公钥验签
     * 
     */
    public static boolean verify(String strData,   
           String strPublicKeyBytes, String strDataSignature) {  
        boolean result = false; 
        byte[] publicKeyBytes = Base64.getDecoder().decode(strPublicKeyBytes);
        try {  
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(  
                    publicKeyBytes);  
  
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);  
  
            Signature signature = Signature.getInstance(RSAHelper.SIGNATURE_ALGORITHM);  
  
            signature.initVerify(publicKey);  
            byte[] data = strData.getBytes();
            signature.update(data);  
            byte[] dataSignature = Base64.getDecoder().decode(strDataSignature);
            result = signature.verify(dataSignature);  
        } catch (Exception ex) {  
            Logger.getLogger(RSAHelper.class.getName()).log(Level.SEVERE, null,  
                    ex);  
        }  
  
        return result;  
    }  
}  